/*
Joseph Ratway
Garrett Brown
Bret Parker
*/

//imports
import java.util.*;


public class Board
{
	BoardSpace[][] currentBoard = new BoardSpace[8][8];
   
	int tempPlayer;
	int player;
    int numMoves;
    int turnCount;
    int endCondition;
	String maxmove;


	
	
	//constructor
	Board(){};
	
	//Utilit functions
	
    // Function to make a deep copy of the Board original
	void deepCopy(Board original)
    {
    //println("deepCopy");
        for(int i = 0; i < original.currentBoard.length; i++)
        {
            for(int j = 0; j < original.currentBoard[0].length; j++)
            {
                BoardSpace temp = new BoardSpace();
                temp.locationValue = original.currentBoard[i][j].locationValue;
                temp.checkLocation = original.currentBoard[i][j].checkLocation;
                temp.lockedSpace = original.currentBoard[i][j].lockedSpace;
                temp.weight = original.currentBoard[i][j].weight;
                currentBoard[i][j] = temp;
            }
        }
		player = original.player;
		numMoves = original.numMoves;
		turnCount = original.turnCount;
		endCondition = original.endCondition;
    }
    
	void printLocValues(BoardSpace[][] boardspace)
	{
	for (int i=0; i < boardspace.length; i++) 
		{
			System.out.print("");
			for (int j=0; j < boardspace[i].length; j++) 
			{
				System.out.print(boardspace[i][j].locationValue);
				System.out.print(" ");
			
			}
			
		System.out.println("");

		}
	}
 
	void printBoard() //Prints the Board
	{	
	  int row = 1;
	  char valToPrint;
	  System.out.println("Turn Count: " + turnCount);
	  String updateScore = "UPDATE";
	
		
	
	  
	  System.out.println("                                         @ = Black, 0 = White");
	  System.out.println("    a   b   c   d   e   f   g   h  ");
	  System.out.println("  +---+---+---+---+---+---+---+---+");
	  for (int i=0; i < currentBoard.length; i++) 
	  {
	  
		System.out.print(row + " |");
		row++;
		
		for (int j=0; j < currentBoard[i].length; j++) 
		{
			if(currentBoard[i][j].locationValue==0)
				valToPrint=' ';
			else if(currentBoard[i][j].locationValue==1)
				valToPrint='@';
			else if(currentBoard[i][j].locationValue==2)
				valToPrint='0';
			else
				valToPrint='X';
		
			System.out.print(" " + valToPrint + " |");
            //System.out.print(" " + currentBoard[i][j].weight + " |");
		}
		System.out.println("");
		System.out.println("  +---+---+---+---+---+---+---+---+");
	  }
	  getScores(updateScore);
	  
	  if(player==2)
			System.out.println("          WHITE'S TURN -> O ");
	  else if(player==1)
			System.out.println("          BLACK's TURN -> @ ");
	  else
			System.out.println("GAME OVER");
	  
	}
	int getValAtPosition(int x, int y) 
	{
		return currentBoard[x][y].locationValue;
	}
	
	boolean isWhiteAtPosition(int x, int y)
	{
		if(currentBoard[x][y].locationValue==2)
			return true;
		else
			return false;
	}
	
	boolean isBlackAtPosition(int x, int y)
	{
		if(currentBoard[x][y].locationValue==1)
			return true;
		else
			return false;
	}
	
	void setValueAtPos(int x, int y, int value)
	{
	
		currentBoard[x][y].locationValue=value;
	
	}
	
	BoardSpace[][] getBoardSpace()
	{
		return currentBoard;
	}
	
	void setBoardSpace(BoardSpace[][] boardspace)
	{
		currentBoard = boardspace;
		System.out.println("TEST");
	}
	
	boolean isPositionEmpty(int x, int y)
	{
		if(currentBoard[x][y].locationValue==0)
			return true;
		else
			return false;
	}
	
	int isValidMove(BoardSpace[][] boardspace)
	{	
	
		int rowInc,colInc;
		int x=0;
		int y=0;
		
		int numMoves=0;
		int opponent=0;
		
		if(player==1)
			opponent=2;
		else
			opponent=1;
			
			
		for (int i=0; i < 8; i++) 
			{
				for (int j=0; j < 8; j++) 
				{
					if(boardspace[i][j].locationValue == 4)
						 boardspace[i][j].locationValue = 0;
						 
				}
			}	
		
		for(int i=0; i < 8 ;i++)
		{
			for(int j=0;j<8;j++)
			{
				if(boardspace[i][j].locationValue!=0)
					continue;
				for(rowInc=-1;rowInc<=1;rowInc++)
					for(colInc=-1;colInc<=1;colInc++)
					{
						if(i+rowInc < 0 || i+rowInc >= 8 || j+colInc < 0 ||
							j+colInc >= 8 || (rowInc == 0 && colInc==0))
							continue;
						if(boardspace[i+rowInc][j+colInc].locationValue==opponent)
						{
							x=i+rowInc;
							y=j+colInc;
							
							for(;;)
							{
								x+=rowInc;
								y+=colInc;
								
								if(x < 0||x >= 8||y < 0||y >= 8)
									break;
								if(boardspace[x][y].locationValue==0)
									break;
								if(boardspace[x][y].locationValue==player)
								{
									boardspace[i][j].locationValue=4;
									numMoves++;
									break;
								}
							}
						}
					}
			}
		}
		
			//System.out.println("number of moves available = " + numMoves);
			return numMoves;	
	}
	
	int changeChartoCol(char ch)
	{
		if(ch=='a')
			return 0;
		else if(ch=='b')
			return 1;
		else if(ch=='c')
			return 2;
		else if(ch=='d')
			return 3;
		else if(ch=='e')
			return 4;
		else if(ch=='f')
			return 5;
		else if(ch=='g')
			return 6;
		else if(ch=='h')
			return 7;
		else
			{
			System.out.println("Parse failed");
			return -1;
			}
			
	}
	
	String changeNumtoChar(int col)
	{
		if(col==0)
			return "a";
		else if(col==1)
			return "b";
		else if(col==2)
			return "c";
		else if(col==3)
			return "d";
		else if(col==4)
			return "e";
		else if(col==5)
			return "f";
		else if(col==6)
			return "g";
		else if(col==7)
			return "h";
		else
			return "You Suck";
	
	}
	
    //Makes the given move, and updates the boardspace
	int makeMove(BoardSpace[][] boardspace, int playermoving, String str)
	{
		
		char[] moveArray = str.toCharArray();
		int col = changeChartoCol(moveArray[0]);
		int row = Character.digit(moveArray[1], 10) - 1;
		int opponent =  0;
		int x = 0;
		int y = 0;
		int rowChange = 0;
		int colChange = 0;
		
		if (player==1)
			opponent=2;
		else
			opponent=1;

		if(col!=-1)
		{
			int validmoves = isValidMove(boardspace);
			if (validmoves > 0)
			{
				endCondition=2;
				if(boardspace[row][col].locationValue == 4)
				{
					boardspace[row][col].locationValue = player;
					 for(rowChange = -1; rowChange <= 1; rowChange++)
						 for(colChange = -1; colChange <= 1; colChange++)
						 {
							if(row + rowChange < 0 || row + rowChange >= 8 ||col + colChange < 0 || col + colChange >= 8 || 
								 (rowChange==0 && colChange== 0))
									continue;
							
							if(boardspace[row+rowChange][col+colChange].locationValue == opponent)
							{
								x=row+rowChange;
								y=col+colChange;
								for(;;)
								{
									x+=rowChange;
									y+=colChange;
									if(x<0||x>=8||y<0||y>=8)
										break;
									if(boardspace[x][y].locationValue == 0)
										break;
									if(boardspace[x][y].locationValue == player)
									{
										while(boardspace[x-=rowChange][y-=colChange].locationValue==opponent)
											boardspace[x][y].locationValue=player;
										break;
									}
								}
							}
						}
						
					for (int i=0; i < 8; i++) 
					{
						for (int j=0; j < 8; j++) 
						{
							if(boardspace[i][j].locationValue == 4)
								 boardspace[i][j].locationValue = 0; 
						}
					}
					
					if(player == 1)
						player=2;
					else
						player=1;
					
					
					
					numMoves++;
					turnCount++;
					
				return 1;
				
				}
				else
				{
					System.out.println("Not a good move");
					return -1;
				}
			}
			else
			{
				if(endCondition > 0)
				{
					if(playermoving==2)
					{
						System.out.println("No more valid moves for WHITE ");
						player=1;
						tempPlayer=1;
						endCondition--;
					}
					else
					{
						System.out.println("No more valid moves for BLACK ");
						player=2;
						tempPlayer=2;
						endCondition--;
					}
				}
			}
		}
		else
		{
			System.out.println("Parse 2 failed");
			System.exit(1);
		}
		
		
		return 0;
	}
	
	void getScores(String str)
	{
		int whitePieces=0;
		int blackPieces=0;
	
		for (int i=0; i < 8; i++) 
			{
				for (int j=0; j < 8; j++) 
					{
						if(currentBoard[i][j].locationValue==1)
						{
							blackPieces++;
						}
						else if(currentBoard[i][j].locationValue==2)
						{
							whitePieces++;
						}
					}
			}
	
	
	if(str=="UPDATE")
		{
			System.out.println("                                           White: " + whitePieces + " Black: " + blackPieces);
		}
	else
		{
			System.out.println("     FINAL SCORE: White: " + whitePieces + " Black: " + blackPieces);
		}
		
	}
	
	void random(BoardSpace[][] boardspace)
	{
		int validmoves=isValidMove(boardspace);
		int row =(int)(Math.random()*8);
		int column=(int)(Math.random()*8);
		String move="";
		if(validmoves>0)
		{
				if(boardspace[row][column].locationValue==4)
				{
					row++;
					if(column==0)
						move="a"+row;
					else if(column==1)
						move="b"+row;
					else if(column==2)
						move="c"+row;
					else if(column==3)
						move="d"+row;
					else if(column==4)
						move="e"+row;
					else if(column==5)
						move="f"+row;
					else if(column==6)
						move="g"+row;
					else if(column==7)
						move="h"+row;
					
					//System.out.println(move);
				
					makeMove(boardspace, player, move);
	
				}
				else
					random(boardspace);
	
		}
		
		else
		{
			System.out.println("No valid moves for player");
			endCondition--;
			
			if(player==2)
				player=1;
			else
				player=2;
			
		}
			
	}
	
	void easy(BoardSpace[][] boardspace)
	{
		int validmoves=isValidMove(boardspace);
		int rowChange = 0;
		int colChange = 0;
		int maxSpaces=0;
		int maxRow=0;
		int maxCol=0;
		int x=0;
		int y=0;
		int opponent=0;
		int numSpaces=0;
		System.out.println("Max Spaces= "+maxSpaces);
		
		if (player==1)
			opponent=2;
		else
			opponent=1;
			if (validmoves > 0)
			{
				for(int i=0;i<8;i++)
					for(int j=0;j<8;j++)
					{
						if(boardspace[i][j].locationValue == 4)
						{
							 for(rowChange = -1; rowChange <= 1; rowChange++)
								 for(colChange = -1; colChange <= 1; colChange++)
								 {
									if(i + rowChange < 0 || i + rowChange >= 8 ||j + colChange < 0 || j + colChange >= 8 || 
										 (rowChange==0 && colChange== 0))
											continue;
									
									if(boardspace[i+rowChange][j+colChange].locationValue == opponent)
									{
										x=i+rowChange;
										y=j+colChange;
										for(;;)
										{
											x+=rowChange;
											y+=colChange;
											if(x<0||x>=8||y<0||y>=8)
												break;
											if(boardspace[x][y].locationValue == 0)
												break;
											if(boardspace[x][y].locationValue == player)
											{
												numSpaces=0;										
												while(boardspace[x-=rowChange][y-=colChange].locationValue==opponent)
													numSpaces++;	
												break;
											}
										}
									}
								}
								if(maxSpaces<numSpaces)
								{
									maxSpaces=numSpaces;
									maxRow=i;
									maxCol=j;
								}
						}
						
					}
			}
			String move="";
			System.out.println("Max Tiles gained="+maxSpaces);
			maxRow++;
			move=changeNumtoChar(maxCol)+maxRow;
			System.out.println("EASY MOVE="+ move);
			makeMove(boardspace, player, move);
	}

	int hard(BoardSpace[][] boardspace,int depth,int maxSpaces,String maxmove)
    {
        int max_depth = 5;
		int temp1;
		ArrayList<String> moves = new ArrayList<String>();
        //move below stuff
        int valid=simisValidMove(boardspace);
		int realvalid = isValidMove(boardspace);
		
		if(realvalid==0)
		{
			endCondition--;
		}
		
		
		if(depth==max_depth)
		{
			return maxSpaces;
		}//
		else
		if(valid>0)
		{
			for(int i = 0; i < 8; i++)
			{
				for(int j = 0; j < 8; j++)
				{
					if(boardspace[i][j].locationValue == 4)
					{
						i++;
						moves.add(changeNumtoChar(j)+i);
						i = i - 1;
					}
				}
			}
		}
		/*for(int i=0;i<moves.size();i++)
			System.out.println("Array="+moves.get(i));
		System.out.println("--");*/
		
		if(moves.size()!=0)
		{
			//System.out.println("Test1");
			//System.out.println("Test2");
			for(int i = 0; i < moves.size(); i++)
			{	
				//System.out.println("Test3");
				BoardSpace[][] testing=new BoardSpace[8][8];
				//System.out.println("SIZE="+moves.size());
				//System.out.println("I="+i);
				for(int z = 0; z < boardspace.length; z++)
				{
					//System.out.println("Test4");
					for(int j = 0; j < boardspace[0].length; j++)
					{
						//System.out.println("Test5");
						BoardSpace temp = new BoardSpace();
						temp.locationValue = boardspace[z][j].locationValue;
						temp.checkLocation = boardspace[z][j].checkLocation;
						temp.lockedSpace = boardspace[z][j].lockedSpace;
						temp.weight = boardspace[z][j].weight;
						testing[z][j] = temp;
					}
				}  
				
				temp1 = simMove(testing,moves.get(i));
				medium(testing,depth+1,maxSpaces,maxmove);
				
				if(maxSpaces<temp1)
				{
					
					maxSpaces=temp1;
					maxmove=moves.get(i);
				}
				
				
				/*if(maxSpaces<numSpaces)
				{
					maxSpaces=numSpaces;
					maxmove=moves.get(i);
					//System.out.println("BEST MOVE="+maxmove);
				}*/
				
				
				
			}
			if(depth==0)
			{
				System.out.println("MOVE="+maxmove);
				makeMove(currentBoard,player,maxmove);
			}
			return maxSpaces;
		}
        return maxSpaces;
    }
	
	int medium(BoardSpace[][] boardspace,int depth,int maxSpaces,String maxmove)
    {
        int max_depth = 3;
		int temp1;
		ArrayList<String> moves = new ArrayList<String>();
        //move below stuff
        int valid=simisValidMove(boardspace);
		int realvalid=isValidMove(boardspace);
		
		if(realvalid==0)
		{
			endCondition--;
		}
		
		
		if(depth==max_depth)
		{
			return maxSpaces;
		}
		else
		{	
			if(valid>0)
			{
				for(int i = 0; i < 8; i++)
				{
					for(int j = 0; j < 8; j++)
					{
						if(boardspace[i][j].locationValue == 4)
						{
							i++;
							moves.add(changeNumtoChar(j)+i);
							i = i - 1;
						}
					}
				}
			}
			else 
			{
				System.out.println(valid);
				if(tempPlayer==1)
				{
					tempPlayer=2;
				}
				else
				{
					tempPlayer=1;
				}
			}
		}
		/*for(int i=0;i<moves.size();i++)
			System.out.println("Array="+moves.get(i));
		System.out.println("--");*/
		
		if(moves.size()!=0)
		{
			//System.out.println("Test1");
			//System.out.println("Test2");
			for(int i = 0; i < moves.size(); i++)
			{	
				//System.out.println("Test3");
				BoardSpace[][] testing=new BoardSpace[8][8];
				//System.out.println("SIZE="+moves.size());
				//System.out.println("I="+i);
				for(int z = 0; z < boardspace.length; z++)
				{
					//System.out.println("Test4");
					for(int j = 0; j < boardspace[0].length; j++)
					{
						//System.out.println("Test5");
						BoardSpace temp = new BoardSpace();
						temp.locationValue = boardspace[z][j].locationValue;
						temp.checkLocation = boardspace[z][j].checkLocation;
						temp.lockedSpace = boardspace[z][j].lockedSpace;
						temp.weight = boardspace[z][j].weight;
						testing[z][j] = temp;
					}
				}  
				
				temp1 = simMove(testing,moves.get(i));
				
				medium(testing,depth+1,maxSpaces,maxmove);
				if(maxSpaces<temp1)
				{
					maxSpaces=temp1;
					maxmove=moves.get(i);
				}
				
				
				/*if(maxSpaces<numSpaces)
				{
					maxSpaces=numSpaces;
					maxmove=moves.get(i);
					//System.out.println("BEST MOVE="+maxmove);
				}*/
				
				
				
			}
			if(depth==0)
			{
				System.out.println("MOVE="+maxmove);
                System.out.println("Spaces="+maxSpaces);
                /*for(int i=0;i<moves.size();i++)
                    System.out.println("Array="+moves.get(i));*/
				makeMove(currentBoard,player,maxmove);
			
			}
			return maxSpaces;
			
			
			
		}
 
        return maxSpaces;
        
    }
	
	int simMove(BoardSpace[][] boardspace, String str)//actually makes the moves from valid moves
	{
		
		char[] moveArray = str.toCharArray();
		int col = changeChartoCol(moveArray[0]);
		int row = Character.digit(moveArray[1], 10) - 1;
		int opponent =  0;
		int x = 0;
		int y = 0;
		int rowChange = 0;
		int colChange = 0;
		int numSpaces=0;
		
		if (tempPlayer==1)
			opponent=2;
		else
			opponent=1;

		if(col!=-1)
		{
			int validmoves = simisValidMove(boardspace);//checks to see if the space entered is a valid move
			if (validmoves > 0)
			{
				if(boardspace[row][col].locationValue == 4)//finds where the moves are and flips them 
				{
					boardspace[row][col].locationValue = tempPlayer;
					 for(rowChange = -1; rowChange <= 1; rowChange++)
						 for(colChange = -1; colChange <= 1; colChange++)
						 {
							if(row + rowChange < 0 || row + rowChange >= 8 ||col + colChange < 0 || col + colChange >= 8 || 
								 (rowChange==0 && colChange== 0))
									continue;
							
							if(boardspace[row+rowChange][col+colChange].locationValue == opponent)
							{
								x=row+rowChange;
								y=col+colChange;
								for(;;)
								{
									x+=rowChange;
									y+=colChange;
									if(x<0||x>=8||y<0||y>=8)
										break;
									if(boardspace[x][y].locationValue == 0)
										break;
									if(boardspace[x][y].locationValue == tempPlayer)
									{
										while(boardspace[x-=rowChange][y-=colChange].locationValue==opponent)
										{
											boardspace[x][y].locationValue=tempPlayer;
											numSpaces++;
										}
										break;
									}
								}
							}
						}
					
					if(tempPlayer == 1)//switches players after the turn is done
						tempPlayer=2;
					else
						tempPlayer=1;
					//System.out.println(str+" SPACES="+numSpaces);	
					return numSpaces;
				
				}
			}
			/*else
			{
				if(endCondition > 0)//if there are no moves for the player it lets them know and switches 
				{
					if(tempPlayer==2)
					{
						System.out.println("No more valid moves for WHITE ");
						tempPlayer=1;
						endCondition--;
					}
					else
					{
						System.out.println("No more valid moves for BLACK ");
						tempPlayer=2;
						endCondition--;
					}
				}
			}*/
		}
		return 0;
	}
	
	int simisValidMove(BoardSpace[][] boardspace)//checks for the valid moves of the current player
	{	
		int rowInc,colInc;
		int x=0;
		int y=0;
		
		int numMoves=0;
		int opponent=0;
		
		if(tempPlayer==1)//sets the opponenet to the opposite of the current player
			opponent=2;
		else
			opponent=1;
			
		for (int i=0; i < 8; i++) 
			{
				for (int j=0; j < 8; j++) 
				{
					if(boardspace[i][j].locationValue == 4) //sets the previous moves of the last player to empty space
						 boardspace[i][j].locationValue = 0;
						 
				}
			}	
		
		for(int i=0; i < 8 ;i++)
		{
			for(int j=0;j<8;j++)
			{
				if(boardspace[i][j].locationValue!=0)
					continue;
				for(rowInc=-1;rowInc<=1;rowInc++)
					for(colInc=-1;colInc<=1;colInc++)
					{
						if(i+rowInc < 0 || i+rowInc >= 8 || j+colInc < 0 ||
							j+colInc >= 8 || (rowInc == 0 && colInc==0))
							continue;
						if(boardspace[i+rowInc][j+colInc].locationValue==opponent)//finds where the opponet is and finds where the next move can be
						{
							x=i+rowInc;
							y=j+colInc;
							
							for(;;)
							{
								x+=rowInc;
								y+=colInc;
								
								if(x < 0||x >= 8||y < 0||y >= 8)
									break;
								if(boardspace[x][y].locationValue==0)
									break;
								if(boardspace[x][y].locationValue==tempPlayer)
								{
									boardspace[i][j].locationValue=4;
									numMoves++;
									break;
								}
							}
						}
					}
			}
		}
			return numMoves;	
	}
	}





	
	
	
	
	
	
	
	

	